/*
 * (C) Copyright 2013 George Daswani (georgedaswani@gmail.com) and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *    George Daswani (georgedaswani@gmail.com)
 */

package am.api.wrapper;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.pool.KeyedPoolableObjectFactory;
import org.apache.log4j.Logger;

import am.api.AMConnection;
import am.api.model.AMCredential;

public class PooledConnectionFactory implements
		KeyedPoolableObjectFactory<AMCredential, AMConnection> {

	private final static Logger logger = Logger
			.getLogger(PooledConnectionFactory.class);

	private ConnectionPool connectionPool;

	public PooledConnectionFactory(ConnectionPool connectionPool) {
		super();
		this.connectionPool = connectionPool;
	}

	@Override
	public void activateObject(AMCredential credential, AMConnection connection)
			throws Exception {

		if (logger.isDebugEnabled()) {
			logger.debug(String.format("credential: %s, connection: %s",
					credential, connection));
		}
	}

	@Override
	public void destroyObject(AMCredential credential, AMConnection connection)
			throws Exception {

		if (logger.isDebugEnabled()) {
			logger.debug(String.format("credential: %s, connection: %s",
					credential, connection));
		}

		AMConnectionImpl connImpl = (AMConnectionImpl) connection;

		if (connImpl != null && 1 == connImpl.isConnected()) {
			connImpl.reallyClose();
		}
	}

	@Override
	public AMConnection makeObject(AMCredential credential) throws Exception {
		AMConnectionImpl conn = new AMConnectionImpl(connectionPool, credential);
		conn.openConnection(credential.getDatabase(), credential.getUserName(),
				credential.getPassword());
		return conn;
	}

	@Override
	public void passivateObject(AMCredential credential, AMConnection connection)
			throws Exception {

		if (logger.isDebugEnabled()) {
			logger.debug(String.format("credential: %s, connection: %s",
					credential, connection));
		}

	}

	@Override
	public boolean validateObject(AMCredential credential,
			AMConnection connection) {

		if (1 == connection.isConnected()) {
			return true;
		}

		return false;

	}

	public ConnectionPool getConnectionPool() {
		return connectionPool;
	}

	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (obj.getClass() != getClass()) {
			return false;
		}
		PooledConnectionFactory rhs = (PooledConnectionFactory) obj;
		return new EqualsBuilder().append(connectionPool, rhs.connectionPool)
				.isEquals();
	}

	public int hashCode() {
		return new HashCodeBuilder(101, 103).append(connectionPool)
				.toHashCode();
	}

}
